热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Codeforces12D(线段树树状数组

这是前两天10级排位赛数据结构场的题,当时看了没思路就没去做,这两天在学线段树的时候又想到了这道题,拿来一看这么简单。。。题意:n个女孩参加舞会,每个女孩有三个属性,如果一个女孩发现有人三

这是前两天10级排位赛数据结构场的题,当时看了没思路就没去做,这两天在学线段树的时候又想到了这道题,拿来一看这么简单。。。

题意:n个女孩参加舞会,每个女孩有三个属性,如果一个女孩发现有人三项属性都高于自己,她就伤心的跳楼了。。给出n和每个人的属性,问最后有多少人跳楼。

思路:有点类似求逆序数。每个属性的范围是10^9,离散化是必须的了。翅膀先说说自己的做法,其实三个属性都一样的,操作的时候可以任意选取。记三个属性为x、y、z,先按y升序排序,然后给y标号,y相同就标相同的号,标号就是为了离散化~然后按x降序排序,以y为坐标,z为关键字,每次查询区间最大值进行比较、更新即可。可用线段树或树状数组解决。

注意:一个人发现有人比自己强就跳楼了,不要重复统计,不能让人家一直跳楼吧(信春哥,原地满血满状态复活???)

线段树版本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
/*
     algorithm : segment tree
  
     Memory 15100K   Time 1170MS Language G++
  
     code by : zhyu
  */
#include
#include
#include
using namespace std;
  
#define REP(i,n) for(int i=0;i<(n);++i)
#define FOR(i,l,h) for(int i=(l);i<=(h);++i)
#define FORD(i,h,l) for(int i=(h);i>=(l);--i)
  
#define N 500010
  
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1 | 1
  
int tree[N<<2];
struct node
{
     int x,y,z;
}a[N];
  
bool cmpy(node a,node b)
{
     return a.y
}
bool cmpx(node a,node b)
{
     if (a.x==b.x)
     {
         if (a.y!=b.y)    return a.y>b.y;
         return a.z>b.z;
     }
     return a.x>b.x;
}
void PushUp( int rt)
{
     tree[rt]=max(tree[rt<<1],tree[rt<<1|1]);
}
void build( int l, int r, int rt)
{
     tree[rt]=-1;
     if (l==r)    return ;
     int m=(l+r)>>1;
     build(lson);
     build(rson);
}
void update( int p, int val, int l, int r, int rt)
{
     if (l==r)
     {
         tree[rt]=max(tree[rt],val);
         return ;
     }
     int m=(l+r)>>1;
     if (p<=m) update(p,val,lson);
     else    update(p,val,rson);
     PushUp(rt);
}
int query( int L, int R, int l, int r, int rt)
{
     if (L>r)  return -1;
     if (l>=L && r<=R)  return tree[rt];
     int m=(l+r)>>1;
     int res=0;
     if (L<=m) res=max(res,query(L,R,lson));
     if (R>m)      res=max(res,query(L,R,rson));
     return res;
};
int main( void )
{
     int n;
     scanf ( "%d" ,&n);
     FOR(i,1,n)  scanf ( "%d" ,&a[i].x);
     FOR(i,1,n)  scanf ( "%d" ,&a[i].y);
     FOR(i,1,n)  scanf ( "%d" ,&a[i].z);
     sort(a+1,a+n+1,cmpy);
     int pre=a[1].y;
     a[1].y=1;
     FOR(i,2,n)
     {
         int tmp=a[i].y;
         if (a[i].y==pre) a[i].y=a[i-1].y;
         else    a[i].y=a[i-1].y+1;
         pre=tmp;
     }
     int len=a[n].y;
     sort(a+1,a+n+1,cmpx);
     build(1,len,1);
     int ans=0;
     int i=1;
     while (i<=n)
     {
         int j=i;
         while (j<=n && a[i].x==a[j].x)
         {
             if (j<=n && query(a[j].y+1,len,1,len,1)>a[j].z)    ans++;
             j++;
         }
         j=i;
         while (j<=n && a[i].x==a[j].x)
         {
             update(a[j].y,a[j].z,1,len,1);
             j++;
         }
         i=j;
     }
     printf ( "%d\n" ,ans);
     return 0;
}

树状数组版本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
/*
     algorithm : bit
  
     Memory 9200K    Time 920MS  Language G++
  
     code by : zhyu
*/
#include
#include
#include
using namespace std;
  
#define REP(i,n) for(int i=0;i<(n);++i)
#define FOR(i,l,h) for(int i=(l);i<=(h);++i)
#define FORD(i,h,l) for(int i=(h);i>=(l);--i)
  
#define N 500010
  
#define lowbit(x) (x&(-x))
  
struct node
{
     int x,y,z;
}a[N];
int c[N];
int n;
  
bool cmpy(node a,node b)
{
     return a.y
}
bool cmpx(node a,node b)
{
     if (a.x==b.x)
     {
         if (a.y==b.y)    return a.z>b.z;
         return a.y>b.y;
     }
     return a.x>b.x;
}
void update( int x, int val)
{
     while (x>0)
     {
         if (c[x]
         x-=lowbit(x);
     }
}
int getmax( int x)
{
     int res=0;
     while (x<=n)
     {
         if (c[x]>res) res=c[x];
         x+=lowbit(x);
     }
     return res;
}
int main( void )
{
     scanf ( "%d" ,&n);
     FOR(i,1,n)  scanf ( "%d" ,&a[i].x);
     FOR(i,1,n)  scanf ( "%d" ,&a[i].y);
     FOR(i,1,n)  scanf ( "%d" ,&a[i].z);
     sort(a+1,a+n+1,cmpy);
     int pre=a[1].y;
     a[1].y=1;
     FOR(i,2,n)
     {
         int tmp=a[i].y;
         if (a[i].y==pre) a[i].y=a[i-1].y;
         else    a[i].y=a[i-1].y+1;
         pre=tmp;
     }
     sort(a+1,a+n+1,cmpx);
     int ans=0;
     int i=1;
     while (i<=n)
     {
         int j=i;
         while (j<=n && a[i].x==a[j].x)
         {
             if (getmax(a[j].y+1)>a[j].z)  ans++;
             j++;
         }
         j=i;
         while (j<=n && a[i].x==a[j].x)
         {
             update(a[j].y,a[j].z);
             j++;
         }
         i=j;
     }
     printf ( "%d\n" ,ans);
     return 0;
}

推荐阅读
  • 本文介绍如何使用线段树解决洛谷 P1531 我讨厌它问题,重点在于单点更新和区间查询最大值。 ... [详细]
  • 本文整理了一份基础的嵌入式Linux工程师笔试题,涵盖填空题、编程题和简答题,旨在帮助考生更好地准备考试。 ... [详细]
  • 【线段树】  本质是二叉树,每个节点表示一个区间[L,R],设m(R-L+1)2(该处结果向下取整)左孩子区间为[L,m],右孩子区间为[m ... [详细]
  • 2018 HDU 多校联合第五场 G题:Glad You Game(线段树优化解法)
    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6356在《Glad You Game》中,Steve 面临一个复杂的区间操作问题。该题可以通过线段树进行高效优化。具体来说,线段树能够快速处理区间更新和查询操作,从而大大提高了算法的效率。本文详细介绍了线段树的构建和维护方法,并给出了具体的代码实现,帮助读者更好地理解和应用这一数据结构。 ... [详细]
  • 题目描述:给定一个区间,支持两种操作:1. 将位置a的值修改为b;2. 查询区间[a, b]内的子序列的最大和,其中子序列中相邻的元素必须具有不同的奇偶性。 ... [详细]
  • 本文介绍了如何在 Spring Boot 项目中使用 spring-boot-starter-quartz 组件实现定时任务,并将 cron 表达式存储在数据库中,以便动态调整任务执行频率。 ... [详细]
  • 普通树(每个节点可以有任意数量的子节点)级序遍历 ... [详细]
  • T15483.【清华集训2017模拟11.26】简单路径T25484.【清华集训2017模拟11.26】快乐树T35485.【清华集训2017模拟11.26】字符串T1结论题,结论很 ... [详细]
  • 数据结构第三章,栈、队列、数组,期末不挂科指南,第3篇
    数据结构第三章,栈、队列、数组,期末不挂科指南,第3篇,Go语言社区,Golang程序员人脉社 ... [详细]
  • com.sun.javadoc.PackageDoc.exceptions()方法的使用及代码示例 ... [详细]
  • 题目《BZOJ2654: Tree》的时间限制为30秒,内存限制为512MB。该问题通过结合二分查找和Kruskal算法,提供了一种高效的优化解决方案。具体而言,利用二分查找缩小解的范围,再通过Kruskal算法构建最小生成树,从而在复杂度上实现了显著的优化。此方法不仅提高了算法的效率,还确保了在大规模数据集上的稳定性能。 ... [详细]
  • 在尝试对 QQmlPropertyMap 类进行测试驱动开发时,发现其派生类中无法正常调用槽函数或 Q_INVOKABLE 方法。这可能是由于 QQmlPropertyMap 的内部实现机制导致的,需要进一步研究以找到解决方案。 ... [详细]
  • Android中将独立SO库封装进JAR包并实现SO库的加载与调用
    在Android开发中,将独立的SO库封装进JAR包并实现其加载与调用是一个常见的需求。本文详细介绍了如何将SO库嵌入到JAR包中,并确保在外部应用调用该JAR包时能够正确加载和使用这些SO库。通过这种方式,开发者可以更方便地管理和分发包含原生代码的库文件,提高开发效率和代码复用性。文章还探讨了常见的问题及其解决方案,帮助开发者避免在实际应用中遇到的坑。 ... [详细]
  • 【妙】bug称它为数组越界的妙用
    1、聊一聊首先跟大家推荐一首非常温柔的歌曲,跑步的常听。本文主要把自己对C语言中柔性数组、零数组等等的理解分享给大家,并聊聊如何构建一种统一化的学习思想 ... [详细]
  • 在机器学习领域,深入探讨了概率论与数理统计的基础知识,特别是这些理论在数据挖掘中的应用。文章重点分析了偏差(Bias)与方差(Variance)之间的平衡问题,强调了方差反映了不同训练模型之间的差异,例如在K折交叉验证中,不同模型之间的性能差异显著。此外,还讨论了如何通过优化模型选择和参数调整来有效控制这一平衡,以提高模型的泛化能力。 ... [详细]
author-avatar
xwu9052591
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有